/*

1、更改数据结构为weakMap - map - set
2、包装全局的响应式函数
3、抽离出track和trigger函数

待改进：需对trigger取出的effect执行进行判断，死循环

*/

const data = {
    text: "init",
    color: "white"
}
const weakMap = new WeakMap()
let activeEffect

const proxyData = new Proxy(data, {
    get(target, prop) {
        track(target, prop)
        return Reflect.get(...arguments)
    },
    set(target, prop, val) {
        Reflect.set(...arguments)
        trigger(target, prop)
    }
})

function track(target, prop) {
    if (!activeEffect) return
    if (!weakMap.has(target)) weakMap.set(target, new Map())
    const map = weakMap.get(target)
    if (!map.has(prop)) map.set(prop, new Set())
    const set = map.get(prop)
    set.add(activeEffect)
}

function trigger(target, prop) {
    weakMap.get(target).get(prop).forEach(fn => fn());
}

function effect(fn) {
    activeEffect = fn
    fn()
}

function fn() {
    document.body.innerText = proxyData.text
}

function fn2() {
    document.body.style.backgroundColor = proxyData.color
}

effect(fn)
effect(fn2)
setTimeout(() => {
    proxyData.text = "change"
}, 1000)
setTimeout(() => {
    proxyData.color = "pink"
}, 2000)